using System;
using System.Collections;
using System.Data;
using System.Web.UI;
using PHSRAG.Insight21.Common.Pages;
using PHSRAG.Insight21.Context;
using PHSRAG.Insight21.Policy;
using PHSRAG.Security;
using PHSRAG.Utility;

namespace PHSRAG.Insight21
{
    /// <summary>
    /// Summary description for Login.
    /// </summary>
    public partial class SysAdminLoginPage : NoSessionHeartbeatPage
    {
        #region Constants

        public const int TicketLifetime = 60; // Minutes.
        public const int TicketVersion = 1;

        #endregion

        #region Private members

        private ICachePolicy _cachePolicy;
        private ICachePolicy _pageCachePolicy;

        #endregion

        #region Event Handlers

        private void OnLogin(object sender, ImageClickEventArgs e)
        {
            try
            {
                string passwordEntry;
                string userNameEntry = userName.Text.Trim();
                if (userNameEntry.Length == 0)
                {
                    throw new Exception("You must specify the user name of the user you are impersonating.");
                }

                string sysAdminUserNameEntry = sysAdminUserName.Text.Trim();
                if (sysAdminUserNameEntry.Length == 0)
                {
                    throw new Exception("You must specify a system administrator username");
                }

                if (Settings.GetKeyValue("ADAuthentication", false))
                {
                    passwordEntry = password.Text.Trim();
                    if (passwordEntry.Length == 0)
                    {
                        throw new Exception("You must specify a password");
                    }

                    Authenticator.ValidateCredentials(sysAdminUserNameEntry, passwordEntry);
                }

//				((SSO)Application[Global.SSOKey]).Enter("Insight", userNameEntry);
                Login(userNameEntry, sysAdminUserNameEntry);
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred during login";
                annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
            }
        }

        protected void OnPageLoad(object sender, EventArgs e)
        {
            try
            {
                // Pull incoming data out of cache and store under the page's cache
                Hashtable incomingPageHash =
                    _pageCachePolicy.GetCachedObject(Keys.IncomingDataKey) as Hashtable;
                if (incomingPageHash != null)
                {
                    //give teh user feedback if the session has timed out...
                    if (Convert.ToString(incomingPageHash[Keys.SessionHasTimedOutKey]) == "true")
                    {
                        annunciator.Message = "Your session has timed out due to an extended period of inactivity.";
                    }

                    _pageCachePolicy.UnCache(Keys.IncomingDataKey);
                }

                EnableViewState = false;

//				string user = ((SSO)Application[Global.SSOKey]).GetLogin("Insight");
//				if (user != null)
//					Login(user);

                // No additional code is required for page load
            }
            catch (Exception ex)
            {
                annunciator.Title = "Following error(s) occurred during load";
                annunciator.Message = ExceptionReport.GetExceptionInfo(ex, false);
            }
        }

        #endregion

        #region Private methods

        private void Login(string userName, string sysAdminUserNameEntry)
        {
            LoadUserContext(userName, sysAdminUserNameEntry);

            // If a target page is specified on the query string, fill out the requested session data
            // and redirect to the given page. Otherwise, redirect to agreements summary page as normal.
            string targetPage = Settings.GetKeyValue(Request.QueryString["target"], null);
            string queryId = Request.QueryString["queryId"];
            if (targetPage != null && queryId != null)
            {
                Hashtable dictionary = new Hashtable();

                DataSet querySet = DataAccess.GetDataSet(DataAccess.GetConnectionString(), "GetPageQuery",
                    DataAccess.BuildSqlParameterArray("@queryKey", SqlDbType.Int, queryId));
                if (querySet.Tables[0].Rows.Count > 0)
                {
                    string query = (string) (querySet.Tables[0].Rows[0]["pageParameters"]);

                    foreach (string keyValue in query.Split('&'))
                    {
                        string[] keyValueSplit = keyValue.Split('=');
                        dictionary.Add(keyValueSplit[0], keyValueSplit[1]);
                    }

                    _pageCachePolicy.Cache(Keys.IncomingDataKey, dictionary);

                    Page.Response.Redirect(targetPage);
                }
                else
                {
                    dictionary[Keys.ErrorKey] = "Could not transfer to detail page: The URL supplied was incorrectly formed or has expired.";
                    _pageCachePolicy.Cache(Keys.IncomingDataKey, dictionary);
                    Page.Response.Redirect(Settings.GetKeyValue("Header.HomeURL", ""));
                }
            }
            else
            {
                Page.Response.Redirect(Settings.GetKeyValue("Header.HomeURL", ""));
            }
        }

        /// <summary>
        /// Loads a UserContext object based on the passed in domain username,
        /// checks that the user is active and has been granted at least one
        /// role, and adds the information  a session variable.  If the user is
        /// inactive or does not have any roles a system exception is thrown.
        /// </summary>
        /// <param name="userName">Domain user's username</param>
        /// <param name="sysAdminUserNameEntry"></param>
        private void LoadUserContext(string userName, string sysAdminUserNameEntry)
        {
            string connectionString = DataAccess.GetConnectionString();

            UserContext sysAdminUserContext = new UserContext(_cachePolicy);

            sysAdminUserContext.Load(connectionString, sysAdminUserNameEntry);

            //@@@revisit this b/c we should be comparing the application's bitvalue
            //with the user's IsActiveBitMask's bit value's...if there is a match then
            //the user is active for the application.
            if (sysAdminUserContext.IsActiveBitMask <= 1)
            {
                throw new Exception("Unable to log into Insight.  The Sys Admin User is inactive.");
            }

            if (!sysAdminUserContext.IsUserSysAdmin)
            {
                throw new Exception("Unable to log into Insight.  The Sys Admin User specified is not an Insight System Administrator.");
            }

            //get the user's context
            UserContext userContext = new UserContext(_cachePolicy);

            userContext.Load(connectionString, userName);

            //@@@revisit this b/c we should be comparing the application's bitvalue
            //with the user's IsActiveBitMask's bit value's...if there is a match then
            //the user is active for the application.
            if (userContext.IsActiveBitMask <= 1)
            {
                throw new Exception("Unable to log into Insight.  The user is inactive.");
            }
            //@@@revisit this to match on actual roles defined in the db
            if (userContext.ModuleBitmask <= 1)
            {
                throw new Exception("Unable to log into Insight.  You do not have access to at least one module.");
            }

            //now save a new session history entry for the application user
//			userContext.CurrentSessionStartDate = DateTime.Now;
//			userContext.Save(connectionString);

            //save the UserContext in the current cache (using the cache policy).
            userContext.Cache();
        }

        #endregion

        #region Web Form Designer generated code

        /// <summary>
        /// Initializes components/members used by this page.
        /// </summary>
        /// <param name="e"></param>
        protected override void OnInit(EventArgs e)
        {
            InitializeComponent();
            base.OnInit(e);

            _cachePolicy = (Policy.ICachePolicy) Session[Policy.Names.CachePolicyKey];
            _pageCachePolicy = (Policy.ICachePolicy) Session[Policy.Names.PageCachePolicyKey];
        }

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.loginButton.Click += new System.Web.UI.ImageClickEventHandler(this.OnLogin);
            this.Load += new System.EventHandler(this.OnPageLoad);
        }

        #endregion
    }
}